/*
 *   Copyright (C) 2009  Jens Kieselbach
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You may obtain a copy of the License at http://www.gnu.org/licenses/gpl.html
 */
package de.kieselbach.grootional.component

import de.kieselbach.grootional.dialog.*
import de.kieselbach.grootional.value.*
import de.kieselbach.swing.*
import de.kieselbach.swing.activation.*
import java.util.logging.*
import javax.swing.*

import java.awt.Dimension

public class ConnectionListCard extends MainFrameCard {

    def connections
    def model
                       
    ConnectionListCard(def mainframe) {

        this(mainframe, null)
    }

    ConnectionListCard(def mainframe, def tle) {

        super(mainframe)

        title = tle
        icon = uiResources.images['datasources16'] as Icon

        model = new DefaultListModel()
        connections = new JList(model)
        connections.selectionMode = ListSelectionModel.MULTIPLE_INTERVAL_SELECTION

        add(new JScrollPane(connections))

        connections.mouseClicked = {e ->
            if(e.clickCount == 2) {
                connect()
            }
        }

        // -----------------------------------------------------

        def oneactivator = new ListSelectionActivator(connections, 1, 1)

        def button = new FlatButton(uiResources.images['connect16'] as Icon)
        button.toolTipText = resourceBundle.getString('connectionsCard.connect')
        oneactivator.add(button)
        toolBarItems << button
        button.actionPerformed = {
            connect()
        }

        toolBarItems << new CardSeparator()

        button = new FlatButton(uiResources.images['add16'] as Icon)
        button.toolTipText = resourceBundle.getString('connectionsCard.add')
        toolBarItems << button
        button.actionPerformed = {
            addConnection()
        }

        button = new FlatButton(uiResources.images['copy16'] as Icon)
        button.toolTipText = resourceBundle.getString('connectionsCard.copy')
        oneactivator.add(button)
        toolBarItems << button
        button.actionPerformed = {
            editConnection(false)
        }

        button = new FlatButton(uiResources.images['edit16'] as Icon)
        button.toolTipText = resourceBundle.getString('connectionsCard.edit')
        oneactivator.add(button)
        toolBarItems << button
        button.actionPerformed = {
            editConnection(true)
        }

        button = new FlatButton(uiResources.images['delete16'] as Icon)
        button.toolTipText = resourceBundle.getString('connectionsCard.delete')
        new ListSelectionActivator(connections, 1).add(button)
        toolBarItems << button
        button.actionPerformed = {
            deleteConnections()
        }
    }

    void connect() {

        def con = connections.selectedValue
        if(con != null) {
            mainFrame.openDatabaseFrame(con)
        }
    }

    void addConnection() {

        def dlg = new ConnectionDialog(mainFrame)
        dlg.show()

        if(dlg.wasOk) {
            addConnection(dlg.getConnectionValue())
        }
    }

    void addConnection(def con) {

        if(con != null) {
            def desc = con.description ?: ''
            def rename = desc
            def index = null

            def num = 2
            def i = 0
            while(i < model.size() && index == null) {
                def elem = model.elementAt(i)

                if(rename.equalsIgnoreCase(elem.description)) {
                    rename = desc + ' - ' + num
                    num++
                    i = 0
                }
                else {
                    if(rename.compareToIgnoreCase(elem.description) < 0) {
                        index = i
                    }

                    i++
                }
            }

            con.description = rename

            if(index != null) {
                model.add(index, con)
                connections.selectedIndex = index
                connections.ensureIndexIsVisible(index)
            }
            else {
                model.addElement(con)
                connections.selectedIndex = model.size() -1
                connections.ensureIndexIsVisible(model.size() -1)
            }
        }
    }

    void editConnection(def edit) {

        def con = connections.selectedValue
        if(con != null) {
            def dlg = new ConnectionDialog(mainFrame)
            dlg.connectionValue = con
            dlg.show()

            if(dlg.wasOk) {
                if(edit) {
                    model.removeElement(con)
                }
                addConnection(dlg.getConnectionValue())
            }
        }
    }

    void deleteConnections() {

        def sel = connections.selectedIndices
        if(sel != null && sel.length > 0) {
            def panebuilder = new PaneBuilder()
            if(panebuilder.question(resourceBundle.getString('connectionsCard.delete'), message: resourceBundle.getString('connectionsCard.deleteconfirmation'), owner: mainFrame.frame, options: ['yes', 'no'], default: 'yes') == 'yes') {
                (sel as List).sort().reverse().each() {r ->
                    model.removeElementAt(r)
                }
            }
        }
    }

    // --------------------------------------------------------------

    def getConnectionIds() {
        
        def ids = []
        model.elements().each() {con ->
          ids << con.id
        }
        return ids
    }

    void writeContentToXml(def markupbuilder) {

        if(model.size() > 0) {
            markupbuilder.connections() {
                model.elements().each() {con ->
                    connection(id: con.id, description: con.description, driver: con.driver, url: con.url, user: con.user, password: con.password, catalog: con.catalog, schema: con.schema) {
                        if(con.properties != null) {
                            con.properties.each() {p ->
                                property(key: p.key, value: p.value)
                            }
                        }
                    }
                }
            }
        }
    }

    void readContentFromXml(def contentnode) {


        if (contentnode.'connections'.size() == 1) {
            contentnode.'connections'.'connection'.each() {elem ->

                def val = new ConnectionValue()

                def str = elem.'@id'
                if (str != null && str.isLong()) {
                    val.id = Long.parseLong(str as String)
                }
                val.description = elem.'@description'
                val.driver = elem.'@driver'
                val.url = elem.'@url'
                val.user = elem.'@user'
                val.password = elem.'@password'
                val.catalog = elem.'@catalog'
                val.schema = elem.'@schema'

                val.properties = [] as LinkedList

                elem.'property'.each() {prop ->
                    val.properties << new PropertyValue(prop.'@key', prop.'@value');
                }

                model.addElement(val)
            }
        }
        else if (contentnode.'connections'.size() > 1) {
            Logger.getLogger(getClass().name).log(Level.WARNING, 'The settings file is invalid! Unable do read connections card!')
        }
    }
}